
#include "page.h"
#include "log.h"

void init_href(href_t* href)
{
	href->type = eHREF_UNKNOWN;
	memset(href->tip, 0, sizeof(href->tip));
	memset(href->name, 0, sizeof(href->name));
	memset(href->url.szurl, 0,sizeof(href->url.szurl));
}

void del_href(href_t* href)
{
	delete href;
	href = 0;
}

void init_bracketcontent(bracketcontent_t* bracketcontent)
{
	bracketcontent->bracketcontent_type = eMETA;
	bracketcontent->len = 0;
	bracketcontent->p = 0;
}
void del_bracketcontent(bracketcontent_t* bracketcontent)
{
	if(	bracketcontent->p != 0)
	{
		delete[] bracketcontent->p;
		bracketcontent->p = 0;
	}
	bracketcontent->len = 0;
	delete bracketcontent;
	bracketcontent = 0;
}

void init_body(body_t* body)
{
	body->len = 0;
	body->p = 0;
}

void del_body(body_t* body)
{
	if( body->p != 0)
	{
		delete[] body->p;
		body->p = 0;
	}
	body->len  = 0;
}
/*
void init_page(page_t* page)
{
	page->ref_count = 0;
	pthread_mutex_init(&page->locker_ref_count, NULL);
	page->charset_type = eCHARSET_UTF8; //default
	memset(page->title, 0, sizeof(page->title));
	memset(page->host, 0 , sizeof(page->host));
	init_body(&page->body);

}
*/
void increase_page(page_t* page, int count)
{
	pthread_mutex_lock(&page->locker_ref_count);
	page->ref_count+=count;
	pthread_mutex_unlock(&page->locker_ref_count);
}
void del_page(page_t* page)
{
	list<bracketcontent_t*>::iterator it = page->bracketcontents.begin();
	for(; it != page->bracketcontents.end(); it++)
	{
		del_bracketcontent((*it));
	}
	page->bracketcontents.clear();
	
	list<href_t*>::iterator it2 = page->hrefs.begin();
	for(; it2 != page->hrefs.end(); it2++)
	{
		del_href((*it2));
	}
	page->hrefs.clear();
	
	release_keyword((void*)page->keyword);
	
	pthread_mutex_destroy(&page->locker_ref_count);
	
	del_body(&page->body);
	delete page;
	page = 0;
}
int release_page(page_t* page, bool del)
{
	pthread_mutex_lock(&page->locker_ref_count);
	if(page->ref_count > 0)
	{
		page->ref_count--;
		if( page->ref_count > 0)
		{
			pthread_mutex_unlock(&page->locker_ref_count);
			return -1;
		}
	}
	pthread_mutex_unlock(&page->locker_ref_count);
	
	//log
//	map<string, int>::iterator mp;
//	for(mp = page->keywords.begin(); mp != page->keywords.end(); mp++)
//	{
//		
//	}
	if(del)	
		del_page(page);	
	return 0;	
}

int add_href_to_page(char* p, int len, page_t* page)
{
	if( p == 0 || len >= URL_LEN || len <= 0)
		return -1;
		
	//check http:// or https:// or mailto:// or file:/// or ftp://
	// only http now	
	if(!filter_url(p, len))
		return -1;
	
	
	//check if in the end
	char* back_1 = p + len -1;
	char* back_3 = p + len -2;
	char* back_4 = back_3 -1;
	eHREF_TYPE ehref_type =	eHREF_UNKNOWN;
	if( strstr(p, ".jpg") == back_4 ||
		strstr(p, ".ico") == back_4 ||
		strstr(p, ".bmp") == back_4 ||
		strstr(p, ".png") == back_4 ||
		strstr(p, ".gif") == back_4   )
	{
		ehref_type = eHREF_IMG;
	}
	else if( strstr(p, ".zip") == back_4 ||
		     strstr(p, ".rar") == back_4 ||
		     strstr(p, ".tar") == back_4 ||
		     strstr(p, ".gz") == back_3 )
	{
		ehref_type = eHREF_ZIPRAR;
	}	     
	else if( strstr(p, ".wmf") == back_4||
		     strstr(p, ".wmv") == back_4 ||
		     strstr(p, ".asf") == back_4 ||
		     strstr(p, ".avi") == back_4 )
	{
		ehref_type = eHREF_MOVIE; //
	}
	else if( strstr(p, ".flv") == back_4 ||
		     strstr(p, ".swf") == back_4 )
	{
		ehref_type =  eHREF_FLASH;//
	}	
	else if( strstr(p, ".doc") == back_4 ||
		     strstr(p, ".exl") == back_4 )
	{
		ehref_type =  eHREF_DOC;//
	}
	else if( strstr(p, ".js") == back_3 )
	{
		ehref_type =  eHREF_JS;//
	}
	else if( strstr(p, ".css") == back_4 )
	{
		ehref_type =  eHREF_CSS;//
	} 
	else if( strstr(p, ".mp3") == back_4 ||
		     strstr(p, ".mp2") == back_4 ||
		     strstr(p, ".mp4") == back_4 ||
		     strstr(p, ".mid") == back_4 ||
		     strstr(p, ".wav") == back_4 )
	{
		ehref_type = eHREF_MUSIC; //
	}
	else if( strstr(p, ".htm") != 0 || 
	         strstr(p, ".html") != 0)
	{
		ehref_type = eHREF_HTML;
	}
	else if( strstr(p, ".asp") != 0 )
	{
		ehref_type = eHREF_ASP;
	}
	else if( strstr(p, ".jsp") != 0 )
	{
		ehref_type = eHREF_JSP;
	}
	else if( strstr(p, ".php") != 0 )
	{
		ehref_type = eHREF_PHP;
	}
	else if( strstr(p, ".xml") != 0 )
	{
		ehref_type =  eHREF_XML;//
	}
	else
	{
		//maybe http://www.othersite.com
		char* dot = strchr(p, '.');
		if( dot != 0)
		{
			//find the slash after dot, avoid get slash in http://
			char* slash = strchr(dot, '/');
			if( slash == 0)
			{
				// www.other.com
				ehref_type =  eHREF_HTML;
			}
			else if( slash == back_1)
			{
				// www.other.com/ or www.other.com/abc/
				ehref_type =  eHREF_HTML;
			}
			else 
			{
				dot = strchr(slash, '.');
				if( dot == 0)
				{
					// www.other.com/abc , no dot in end
					ehref_type =  eHREF_HTML;
				}
			}
		}
		else
		{
		}
	} 
	
	//which type want 	     
	switch(ehref_type)
	{
	case eHREF_UNKNOWN:
	case eHREF_IMG:
	case eHREF_ZIPRAR:
	case eHREF_MOVIE:
	case eHREF_FLASH:
	case eHREF_DOC:
	case eHREF_JS:
	case eHREF_CSS:
	case eHREF_MUSIC:
		return -1;
		break;
	
	case eHREF_HTML:
	case eHREF_ASP:
	case eHREF_JSP:
	case eHREF_PHP:
	case eHREF_XML:
		break;//go on
	}
	
	//del the last '/' in directory
	// www.abc.com/abc/   --->   www.abc.com/abc
	if( strchr(p, '/') == back_1 )
	{
		len -= 1;
	}
	
	if( len >= URL_LEN)
		return -1;
	
	//get absoulutle path
	// /abc/edf.html
	// ./abc/def.html
	//  abc/def.html
	href_t* href = new href_t;
	init_href(href);
	href->type = ehref_type;
	
	char* dot = strchr(p, '.');
	char* slash = strchr(p, '/');
	char* colon = strchr(p, ':');
	do{
		if( colon != 0 && colon < slash)
		{
			// http://www.abc.com/def.html
			if( len >= URL_LEN)
				break;
			memcpy(href->url.szurl, p, len);
		}
		else if(slash == 0)
		{
			//www.abc.com/def.html
			if( len >= URL_LEN)
				break;
			memcpy(href->url.szurl, p, len);
		}
		else if( slash == p)
		{
			// /abc/def.html
			int hostlen = strlen(page->host);
			if( len +hostlen+1 >= URL_LEN)
				break;
			memcpy(href->url.szurl, page->host, hostlen);
			if(*(page->host+hostlen-1) == '/')
			{
				memcpy(href->url.szurl+hostlen, p+1, len-1); 
			}
			else
			{
				memcpy(href->url.szurl+hostlen, p, len); 
			}
		}
		else if( slash == p + 1 && dot == p)
		{
			//  ./abc/def.html
			int urllen = strlen(page->url.szurl);
			if( len +urllen+1 >= URL_LEN)
				break;
			memcpy(href->url.szurl, page->url.szurl, urllen);
			if(*(page->url.szurl+urllen-1) == '/')
			{
				memcpy(href->url.szurl+urllen, p+2, len-2); 
			}
			else
			{
				memcpy(href->url.szurl+urllen, p+1, len-1); 
			}
		}
		else if( slash > p + 1 && dot > p + 1 && dot > slash)
		{
			// abc/def.html
			int urllen = strlen(page->url.szurl);
			if( len +urllen+1 >= URL_LEN)
				break;
			memcpy(href->url.szurl, page->url.szurl, urllen);
			if(*(page->url.szurl+urllen-1) == '/')
			{
				memcpy(href->url.szurl+urllen, p, len); 
			}
			else
			{
				strcat(href->url.szurl,"/"); 
				memcpy(href->url.szurl+urllen, p, len); 
			}
		}
		else if( slash > p + 1 && dot > p + 1 && dot < slash)
		{
			// www.x.com/abc/def.thml
			if( len  >= URL_LEN)
				break;
			memcpy(href->url.szurl, p, len);	
		}
	
		//if not dot, no url
		if( strchr(p, '.') == 0)
			break;
	
		page->hrefs.push_back(href);
		return 0;
	}while(0);
	del_href(href);
	href = 0;
	return -1;
}
int add_bracketcontent_to_page(char* p, int len, page_t* page)
{
	bracketcontent_t* bc = new bracketcontent_t();
	init_bracketcontent(bc);
	add_to_bracketcontent(p, len, bc);
	page->bracketcontents.push_back(bc);
	return 0;
}
void add_to_bracketcontent(char* p, int len, bracketcontent_t* bracketcontent)
{
	bracketcontent->p = new char[len+1];
	memset(bracketcontent->p, 0 , len+1);
	memcpy(bracketcontent->p, p, len);
	bracketcontent->len = len;
}
